home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / pc / files / dsp / 56200tar.z / 56200tar / 56200 / p5 < prev    next >
Text File  |  1992-04-28  |  25KB  |  510 lines

  1.  
  2.          /***********************************************\
  3.          |**                                           **|
  4.          |**   DSP56200 CHIP DRIVER -ADAPTIVE FILTER   **|
  5.          |**                        -POLLED I/O        **|
  6.          |**                                           **|
  7.          \***********************************************/
  8.  
  9.  
  10.  
  11. /************************************************************************\
  12. *                                                                        *
  13. *   This is an example of a program located in a host processor, used    *
  14. *   to setup and service the DSP56200 as a real-time adaptive filter.    *
  15. *   In this example, the host processor polls a general purpose input    *
  16. *   pin to determine the beginning of a new sample period, signified     *
  17. *   by the reception of a rising edge on the DSP56200's START pin. The   *
  18. *   general purpose input pin is tied directly to the START pin of the   *
  19. *   DSP56200.                                                            *
  20. *                                                                        *
  21. *   This program, written in the language "C", is provided only as an    *
  22. *   example, and will be much faster if translated by the user into the  *
  23. *   assembly language of the host processor.                             *
  24. *                                                                        *
  25. *                                                                        *
  26. *   The example system is configured as shown below:                     *
  27. *                                                                        *
  28. *                                                                        *
  29. *                               ------------                             *
  30. *                               | DSP56200 |                             *
  31. *                               ------------                             *
  32. *                                     ^                                  *
  33. *                                     |                                  *
  34. *                                     v                                  *
  35. *                  -------    ------------------                         *
  36. *          d(t) -->| A/D |--->| Host Processor |                         *
  37. *                  -------    |                |    -------              *
  38. *                             | (contains code |--->| D/A |--> out(t)    *
  39. *                  -------    |  found in this |    -------              *
  40. *         x1(t) -->| A/D |--->|     file)      |                         *
  41. *                  -------    ------------------                         *
  42. *                                                                        *
  43. *                                                                        *
  44. *                    Figure 1. Adaptive Filtering System                 *
  45. *                                                                        *
  46. *                                                                        *
  47. *                                                                        *
  48. *   There is only one DSP56200 in this example (i.e., not multiple       *
  49. *   DSP56200s in cascade), and it is configured as an adaptive filter    *
  50. *   (see Figure 2) by writing the DSP56200's Configuration register.     *
  51. *   Since only 16 bits of the result  are sent to the D/A Converter,     *
  52. *   the output is rounded to a 16 bit result by the DSP56200.            * 
  53. *                                                                        *
  54. *                                                                        *
  55. *                                                                        *
  56. *                                                                        *
  57. *         d(n) -------------------------------                           *
  58. *                                          - |                           *
  59. *                                            v                           *
  60. *                    --------------     +   ---                          *
  61. *        x1(n) ----->|    FIR     |------->| + |-----> out(n)            *
  62. *                    |  Structure |         ---           = -1 * error   *
  63. *                    --------------          |                           *
  64. *                          ^                 |                           *
  65. *                          |                 |                           *
  66. *                          -------------------                           *
  67. *                                                                        *
  68. *                                                                        *
  69. *                   Figure 2. DSP56200 Configuration                     *
  70. *                                                                        *
  71. *                                                                        *
  72. *                                                                        *
  73. *      ************************************************************      *
  74. *      *                                                          *      *
  75. *      *   This program originally available on the Motorola DSP  *      *
  76. *      *   bulletin board.  It is provided under a DISCLAMER OF   *      *
  77. *      *   WARRANTY available from  Motorola DSP Operation,       *      *
  78. *      *     6501 Wm. Cannon Drive W., Austin, Tx., 78735.        *      *
  79. *      *                                                          *      *
  80. *      ************************************************************      *
  81. *                                                                        *
  82. *                                                                        *
  83. *                                                                        *
  84. *                                                                        *
  85. *      ************************************************************      *
  86. *      * Note on the Representation of Hex Numbers:               *      *
  87. *      *                                                          *      *
  88. *      *    In the programming language  "C",  hex numbers are    *      *
  89. *      *    represented by preceding the number with "0x". For    *      *
  90. *      *    example, e4 (hex) is represented in "C" as 0xe4.      *      *
  91. *      *                                                          *      *
  92. *      ************************************************************      *
  93. *                                                                        *
  94. \************************************************************************/
  95.  
  96.  
  97.  
  98.         /*** CONSTANTS ***/
  99.  
  100. #define   FOREVER     1         /* For infinite looping */
  101.  
  102.  
  103.  
  104. #define   X1_HI     0x0         /* Addresses (hex) of DSP56200 regs, bank 0 */
  105. #define   X1_LO     0x1
  106. #define   D_HI      0x2
  107. #define   D_LO      0x3
  108. #define   K_HI      0x4
  109. #define   K_LO      0x5
  110. #define   X2_HI     0x6                     /* unused -Dual FIR mode only */
  111. #define   X2_LO     0x7                     /* unused -Dual FIR mode only */
  112. #define   DATA_HI   0x8                     /* unused */
  113. #define   DATA_LO   0x9                     /* unused */
  114. #define   COEFF_HI  0xa
  115. #define   COEFF_MD  0xb
  116. #define   COEFF_LO  0xc
  117. #define   RAM_ADR   0xd
  118. #define   CONFIG    0xf
  119.  
  120. #define   OUTPUT3   0x0               /* Most  significant byte of result */
  121. #define   OUTPUT2   0x1
  122. #define   OUTPUT1   0x2               /* Two least significant bytes are  */
  123. #define   OUTPUT0   0x3               /* unused since rounded to 16 bits */
  124. #define   LTAP1_HI  0x4                     /* unused */
  125. #define   LTAP1_LO  0x5                     /* unused */
  126. #define   LTAP2_HI  0x6                     /* unused */
  127. #define   LTAP2_LO  0x7                     /* unused */
  128.  
  129. #define   LEAKAGE   0x0         /* Addresses (hex) of DSP56200 regs, bank 1 */
  130. #define   FTL       0x1
  131.  
  132.  
  133.  
  134. #define   LKG_VAL   0x00        /* Values (hex) written to the DSP56200 regs */
  135. #define   FTL_VAL   0xff              /* 256 taps */
  136. #define   DCONFIG_0 0x98              /* Updates disabled, Selects bank 0   */
  137. #define   DCONFIG_1 0x99              /* Updates disabled, Selects bank 1   */
  138. #define   ECONFIG_0 0x90              /* Updates enabled,  Selects bank 0   */
  139. #define   KVAL_HI   0x04
  140. #define   KVAL_LO   0x00              /* It may be desirable to make the K 
  141.                                          register a variable so it can be 
  142.                                          updated every sample period.   */
  143.  
  144.  
  145.  
  146.         /*** MAIN PROGRAM ***/
  147.  
  148. main()   {
  149.  
  150.         /********************************************************************\
  151.         *                                                                    *
  152.         *   This program is an example of the software used by a host        *
  153.         *   processor to service a DSP56200 configured as an adaptive        *
  154.         *   filter.  Three functions are performed:                          *
  155.         *                                                                    *
  156.         *         1. Initialize User's System and Configure the DSP56200.    *
  157.         *         2. Zero the Coeff and Data RAMs of the DSP56200.           *
  158.         *         3. Run the Adaptive Filter in a real-time environment.     *
  159.         *                                                                    *
  160.         *   Things to watch for when setting up an adaptive filter system:   *
  161.         *                                                                    *
  162.         *         - There must be NO GLITCHES on the DSP56200's START pin.   *
  163.         *         - The SEI pin must be directly wired to the SSO pin.       *
  164.         *         - The value of the K register must not be too large.       *
  165.         *         - If codecs are used for the A/D or D/A conversion, see    *
  166.         *              comments in the routines "send_da()"and "get_ad()".   *
  167.         *         - If offset binary A/Ds or D/As are used, see comments     *
  168.         *              in the subroutines "send_da()" and "get_ad()".        *
  169.         *                                                                    *
  170.         *   Note: The program assumes that the variable type "int" is at     *
  171.         *         least 16 bits wide.                                        *
  172.         *                                                                    *
  173.         \********************************************************************/
  174.  
  175.  
  176.  
  177.         /* Program Declarations */
  178.  
  179.            int tap;                        /* filter tap number */
  180.  
  181.  
  182.  
  183.         /* Initialize System */
  184.  
  185.            /*  Here the user first initializes any other components of the  */
  186.            /*  adaptive filtering system which require initialization. The  */
  187.            /*  DSP56200 is then initialized using the program code below.   */
  188.  
  189.  
  190.  
  191.         /* Reset and Configure the DSP56200 */
  192.  
  193.            wait_for_start();               /* This is done to synchronize   */
  194.                                            /* the program up to the system. */
  195.                                            /* Ensures that no writes occur  */
  196.                                            /* when the DSP56200's START pin */
  197.                                            /* receives a rising edge.       */
  198.  
  199.            wrbyte(DCONFIG_1, CONFIG);      /* Configuration:                */
  200.                                            /*    - Single Adaptive Filter   */
  201.                                            /*    - Not Cascaded             */
  202.                                            /*    - 16 Bit Rounding          */
  203.                                            /*    - Coeff Update Disabled    */
  204.                                            /*    - DC Tap Disabled          */
  205.                                            /*    - Leakage Disabled         */
  206.                                            /*    - Register Bank 1 Selected */
  207.            wrbyte(FTL_VAL, FTL);           /* Writing this reg also resets   */
  208.                                            /*    the chip at the beginning   */
  209.                                            /*    of the next sample period,  */
  210.                                            /*    which destroys any previous */
  211.                                            /*    contents of the Data RAM.   */
  212.            wrbyte(LKG_VAL, LEAKAGE);
  213.  
  214.            wrbyte(DCONFIG_0, CONFIG);      /* Switch to register bank 0 */
  215.  
  216.            wrbyte(KVAL_HI, K_HI);
  217.            wrbyte(KVAL_LO, K_LO);
  218.  
  219.            /* Presently for initialization, there are fourteen writes */
  220.            /* which the host processor must  perform in one sample    */
  221.            /* period.  If all these writes cannot be performed in one */
  222.            /* sample period, a call to the routine "wait_for_start()" */
  223.            /* can be inserted here,  and will reduce the number of    */
  224.            /* writes down to a maximum of eight in one sample period. */
  225.  
  226.  
  227.  
  228.  
  229.         /* Initialize the DSP56200's Coefficient and Data RAMS */
  230.  
  231.               wrbyte(0, X1_HI);
  232.               wrbyte(0, X1_LO);
  233.  
  234.               wrbyte(0, D_HI);
  235.               wrbyte(0, D_LO);
  236.  
  237.               wrbyte(0, COEFF_HI);      /* Coeff_RAM[0] = 0 */
  238.               wrbyte(0, COEFF_MD);
  239.               wrbyte(0, COEFF_LO);
  240.  
  241.               wrbyte(0, RAM_ADR);       /* autoincrements w/ each START */
  242.  
  243.               wait_for_start();
  244.  
  245.               for (tap=1; tap<=FTL_VAL; tap=tap+1)   {
  246.  
  247.                  wrbyte(0, COEFF_HI);      /* Coeff_RAM[tap] = 0 */
  248.                  wrbyte(0, COEFF_MD);
  249.                  wrbyte(0, COEFF_LO);
  250.                                        /*  Note that the Data RAM is also   */
  251.                                        /*  cleared since the DSP56200's X1  */
  252.                                        /*  reg is set to "0", resulting in  */
  253.                                        /*  "0"s being "shifted" into the    */
  254.                                        /*  filter's Data RAM (delay line)   */
  255.                                        /*  every sample period.             */
  256.  
  257.                  wait_for_start();
  258.               }
  259.  
  260.  
  261.  
  262.         /* Enable Coefficient Updates   -toggles bit 3 to a "0" */
  263.  
  264.            wrbyte(ECONFIG_0, CONFIG);
  265.  
  266.  
  267.  
  268.         /* Run the Adaptive Filter in Real-time */
  269.  
  270.               prealtime();
  271. }
  272.  
  273.  
  274.  
  275.         /*** SUBROUTINES ***/
  276.  
  277.  
  278.  
  279.         /* PREALTIME */
  280.  
  281. prealtime()
  282. {
  283.         /****************************************************************\
  284.         *                                                                *
  285.         *   This routine performs the I/O servicing required when the    *
  286.         *   DSP56200 is processing real-time samples.  Every sample      *
  287.         *   period (signified by the reception of a rising edge on the   *
  288.         *   DSP56200's START pin), the host processor sends two new      *
  289.         *   samples to the DSP56200, and reads out a result from the     *
  290.         *   DSP56200.                                                    *
  291.         *                                                                *
  292.         *   This routine is used only in polled I/O systems.             *
  293.         *                                                                *
  294.         *   Note: The routine assumes that the variable type "int" is    *
  295.         *         at least 16 bits wide.                                 *
  296.         *                                                                *
  297.         *   Also: The DSP56200 outputs "-1 * error".  If the correct     *
  298.         *         sign for the error term is required, then the host     *
  299.         *         processor must perform a 2's complement operation      *
  300.         *         on the 16 bit value read from the DSP56200's OUTPUT    *
  301.         *         register (bytes 3 and 2).                              *
  302.         *                                                                *
  303.         *   Also: It is important that execution of the code inside the  *
  304.         *         while loop completes before the next sample period     *
  305.         *         begins.  This guarantees that the start of the next    *
  306.         *         sample period is never missed because the program will *
  307.         *         then be in the subroutine "wait_for_start()", polling  *
  308.         *         for the rising edge of the START signal.               *
  309.         *                                                                *
  310.         \****************************************************************/
  311.  
  312.  
  313.  
  314.         /* Subroutine Declarations */
  315.            int x1, d, out;                        /* see Figure 2 */
  316.  
  317.  
  318.  
  319.         while (FOREVER)   {                       /* infinite loop */
  320.  
  321.            /* Poll for Reception of the START signal */
  322.               wait_for_start();
  323.  
  324.            /* Host Now Services the DSP56200 Since START Has Been Received */
  325.            
  326.               /* Read New Samples from the A/Ds and Write to the DSP56200 */
  327.  
  328.                  x1 = get_ad(1);
  329.                  d  = get_ad(2);
  330.  
  331.                  wrbyte((x1>>8) & 0x0ff, X1_HI);      /* writes upper byte */
  332.                  wrbyte( x1     & 0x0ff, X1_LO);      /* writes lower byte */
  333.                  wrbyte((d>>8)  & 0x0ff, D_HI);       /* writes upper byte */
  334.                  wrbyte( d      & 0x0ff, D_LO);       /* writes lower byte */
  335.  
  336.               /* Read Error Term from the 56200 and Write to the D/A */
  337.    
  338.                  out = rdbyte(OUTPUT3);
  339.                  out = out << 8;                      /* move to upper byte */
  340.                  out = out + (0x0ff & rdbyte(OUTPUT2));
  341.  
  342.                  send_da(out);
  343.         }
  344. }
  345.  
  346.  
  347.  
  348.         /* WRBYTE */
  349.  
  350. wrbyte(val,adr)
  351. int val, adr;
  352. {
  353.         /**************************************************************\
  354.         *                                                              *
  355.         *   This subroutine writes one byte to the DSP56200 register   *
  356.         *   specified by "adr".                                        *
  357.         *   Note that the correct register bank has already been       *
  358.         *   selected (defined by the LSB of the Configuration reg).    *
  359.         *                                                              *
  360.         *   This subroutine could be defined as a macro for faster     *
  361.         *   execution.                                                 *
  362.         *                                                              *
  363.         *   Inputs:                                                    *
  364.         *      val  = bytewide value to be written to the DSP56200     *
  365.         *      adr  = address of the DSP56200 register to be written   *
  366.         *                                                              *
  367.         \**************************************************************/
  368.  
  369.         /* Actual program code depends on the user's system. */
  370. }
  371.  
  372.  
  373.  
  374.         /* RDBYTE */
  375.  
  376. rdbyte(adr)
  377. int adr;
  378. {
  379.         /**************************************************************\
  380.         *                                                              *
  381.         *  This subroutine reads one byte from the DSP56200 register   *
  382.         *  specified by "adr".                                         *
  383.         *  Note that the correct register bank has already been        *
  384.         *  selected (defined by the LSB of the Configuration reg).     *
  385.         *                                                              *
  386.         *  This subroutine could be defined as a macro for faster      *
  387.         *   execution.                                                 *
  388.         *                                                              *
  389.         *   Inputs:                                                    *
  390.         *      adr  = address of the DSP56200 register to be read      *
  391.         *                                                              *
  392.         *   Outputs:                                                   *
  393.         *      The routine returns the byte read from the DSP56200     *
  394.         *                                                              *
  395.         \**************************************************************/
  396.  
  397.         int valread;
  398.  
  399.         /* Actual program code depends on the user's system. */
  400.  
  401.         return(valread);
  402. }
  403.  
  404.  
  405.  
  406.         /* GET_AD */
  407.  
  408. get_ad(devnum)
  409. int devnum;
  410. {
  411.         /******************************************************************\
  412.         *                                                                  *
  413.         *   This subroutine returns a 16 bit value read from one of the    *
  414.         *   two A/D converters in the filtering system.                    *
  415.         *                                                                  *
  416.         *   Inputs:                                                        *
  417.         *      devnum = A/D Converter number:  1 = x1 input, 2 = d input.  *
  418.         *                                                                  *
  419.         *   Outputs:                                                       *
  420.         *      The routine returns the value read from the selected A/D.   *
  421.         *                                                                  *
  422.         \******************************************************************/
  423.  
  424.         int ad_val;
  425.  
  426.         /* Actual program code depends on the user's system. */
  427.  
  428.         /*  If a codec is used for A/D conversion, the 8 bit companded  */
  429.         /*  sample must be converted into a 12 bit linear quantity and  */
  430.         /*  then sign extended to 16 bits.                              */
  431.  
  432.         /*  If the converter uses an offset binary format, it may be  */
  433.         /*  necessary to invert the sign bit (and any sign extension  */
  434.         /*  bits) to obtain a 2's complement number.                  */
  435.  
  436.         return(ad_val);
  437. }
  438.  
  439.  
  440.  
  441.         /* SEND_DA */
  442.  
  443. send_da(val)
  444. int val;
  445. {
  446.         /**************************************************************\
  447.         *                                                              *
  448.         *   This subroutine sends a value to a D/A converter where it  *
  449.         *   gets converted to an analog signal.                        *
  450.         *                                                              *
  451.         *   Inputs:                                                    *
  452.         *      val = value to be sent to the D/A converter             *
  453.         *                                                              *
  454.         \**************************************************************/
  455.  
  456.         /* Actual program code depends on the user's system. */
  457.  
  458.         /*  If a codec is used for D/A conversion, the 16 bit linear   */
  459.         /*  sample must be converted into a 8 bit companded quantity.  */
  460.  
  461.         /*  If the converter uses an offset binary format, it may be  */
  462.         /*  necessary to invert the sign bit (and any sign extension  */
  463.         /*  bits) to obtain a number in offset binary format.         */
  464. }
  465.  
  466.  
  467.  
  468.         /* WAIT_FOR_START */
  469.  
  470. wait_for_start()
  471. {
  472.         /********************************************************************\
  473.         *                                                                    *
  474.         *   This routine polls a general purpose input pin for a "1",        *
  475.         *   which indicates that a rising edge has arrived at the START pin  *
  476.         *   of the DSP56200 and that new samples are ready to be processed.  *
  477.         *                                                                    *
  478.         *   Note: It may be necessary to verify that the START signal has    *
  479.         *         returned to a "0" before polling for a "1".                *
  480.         *                                                                    *
  481.         *   Note: It is important that the program has completed other       *
  482.         *         processing and is waiting in this loop when the START      *
  483.         *         signal arrives so that no samples are lost.                *
  484.         *                                                                    *
  485.         \********************************************************************/
  486.  
  487.         int pin;
  488.  
  489.         pin = get_pin();
  490.  
  491.         while (pin == 0);                /* loops until "1" found on pin */
  492.            pin = get_pin();
  493. }
  494.  
  495.  
  496.  
  497.         /* GET_PIN */
  498.  
  499. get_pin()
  500. {
  501.         /*****************************************************************\
  502.         *                                                                 *
  503.         *   Returns the value read (0 or 1) from a general purpose input  *
  504.         *   pin which is tied directly to the DSP56200's START pin.       *
  505.         *                                                                 *
  506.         \*****************************************************************/
  507.         
  508.         /* Actual program code depends on the user's system. */
  509. }
  510.